// Copyright 2016-present the Material Components for iOS authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import "MaterialTextFields.h"

@interface TextFieldManualLayoutLegacyExample : UIViewController <UITextFieldDelegate>

@property(nonatomic) MDCTextInputControllerLegacyDefault *nameController;
@property(nonatomic) MDCTextInputControllerLegacyDefault *phoneController;

@end

@implementation TextFieldManualLayoutLegacyExample

- (void)viewDidLoad {
  [super viewDidLoad];

  self.view.backgroundColor = [UIColor whiteColor];
  MDCTextField *textFieldName = [[MDCTextField alloc] init];
  [self.view addSubview:textFieldName];

  textFieldName.delegate = self;
  textFieldName.clearButtonMode = UITextFieldViewModeUnlessEditing;

  self.nameController =
      [[MDCTextInputControllerLegacyDefault alloc] initWithTextInput:textFieldName];

  textFieldName.frame = CGRectMake(10, 40, CGRectGetWidth(self.view.bounds) - 20, 0);

  self.nameController.placeholderText = @"Full Name";

  MDCTextField *textFieldPhone = [[MDCTextField alloc] init];
  [self.view addSubview:textFieldPhone];

  textFieldPhone.delegate = self;
  textFieldPhone.clearButtonMode = UITextFieldViewModeUnlessEditing;

  self.phoneController =
      [[MDCTextInputControllerLegacyDefault alloc] initWithTextInput:textFieldPhone];

  textFieldPhone.frame = CGRectMake(10, CGRectGetMaxY(self.nameController.textInput.frame) + 20,
                                    CGRectGetWidth(self.view.bounds) - 20, 0);

  self.phoneController.placeholderText = @"Phone Number";
  self.phoneController.helperText = @"XXX-XXX-XXXX";
}

- (void)viewDidLayoutSubviews {
  [super viewDidLayoutSubviews];

  [self.nameController.textInput sizeToFit];
  [self.phoneController.textInput sizeToFit];
  self.phoneController.textInput.frame = CGRectMake(
      10, CGRectGetMaxY(self.nameController.textInput.frame) + 20,
      CGRectGetWidth(self.view.bounds) - 20, CGRectGetHeight(self.phoneController.textInput.frame));
}

#pragma mark - UITextFieldDelegate

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
  [textField resignFirstResponder];

  if (textField == (UITextField *)self.phoneController.textInput &&
      ![self isValidPhoneNumber:textField.text partially:NO]) {
    [self.phoneController setErrorText:@"Invalid Phone Number" errorAccessibilityValue:nil];
  }

  return NO;
}

- (BOOL)textField:(UITextField *)textField
    shouldChangeCharactersInRange:(NSRange)range
                replacementString:(NSString *)string {
  NSString *finishedString = [textField.text stringByReplacingCharactersInRange:range
                                                                     withString:string];

  if (textField == (UITextField *)self.nameController.textInput) {
    if ([finishedString rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].length &&
        ![self.nameController.errorText isEqualToString:@"You cannot enter numbers"]) {
      // The entered text contains numbers and we have not set an error
      [self.nameController setErrorText:@"You cannot enter numbers" errorAccessibilityValue:nil];

      // Since we are doing manual layout, we need to react to the expansion of the input that will
      // come from setting an error.
      [self.view setNeedsLayout];
    } else if (self.nameController.errorText != nil) {
      // There should be no error but error text is being shown.
      [self.nameController setErrorText:nil errorAccessibilityValue:nil];

      // Since we are doing manual layout, we need to react to the contraction of the input that
      // will come from setting an error.
      [self.view setNeedsLayout];
    }
  }

  if (textField == (UITextField *)self.phoneController.textInput) {
    if (![self isValidPhoneNumber:finishedString partially:YES] &&
        ![self.phoneController.errorText isEqualToString:@"Invalid phone number"]) {
      // The entered text is not valid and we have not set an error
      [self.phoneController setErrorText:@"Invalid phone number" errorAccessibilityValue:nil];

      // The text field has helper text that already expanded the frame so we don't need to call
      // setNeedsLayout.
    } else if (self.phoneController.errorText != nil) {
      [self.phoneController setErrorText:nil errorAccessibilityValue:nil];

      // The text field has helper text and cannot contract the frame so we don't need to call
      // setNeedsLayout.
    }
  }

  return YES;
}

#pragma mark - Phone Number Validation

- (BOOL)isValidPhoneNumber:(NSString *)inputString partially:(BOOL)isPartialCheck {
  // In real life there would be much more robust validation that takes locale into account, checks
  // against invalid phone numbers (like those that begin with 0), and perhaps even auto-inserts the
  // hyphens so the user doesn't have to.

  if (inputString.length == 0) {
    return YES;
  }

  NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789-"];
  characterSet = [characterSet invertedSet];

  BOOL isValid = ![inputString rangeOfCharacterFromSet:characterSet].length;

  if (!isPartialCheck) {
    isValid = isValid && inputString.length == 12;
  } else {
    isValid = isValid && inputString.length <= 12;
  }
  return isValid;
}

@end

@implementation TextFieldManualLayoutLegacyExample (CatalogByConvention)

+ (NSDictionary *)catalogMetadata {
  return @{
    @"breadcrumbs" : @[ @"Text Field", @"[Legacy] Manual Layout" ],
    @"primaryDemo" : @NO,
    @"presentable" : @NO,
  };
}

@end
